#ifndef PIZZAORDER_HPP_
# define PIZZAORDER_HPP_

# include <map>
# include <list>
# include <string>
# include "Utils/macros.hpp"
# include "Utils/Tokenizer.hpp"
# include "Pizzeria/Pizza.hpp"

namespace pizzeria {

class PizzaOrderParser {
public:
  /*! Constructor.
   * Parse the given order and put corresponding \a Pizza objects into a
   * std::list (see GetPizzaList()).
   * \param order : the customer's order
   * \throw std::invalid_argument if the input string is not valid or
   * 				  contains errors
   */
  PizzaOrderParser(const std::string &order);
  /*! Destructor */
  ~PizzaOrderParser();

  /*! Get the pizza list
   * \return A std::list containing \a Pizza objects corresponding to the
   * customer order given to PizzaOrder().
   */
  std::list<Pizza> &GetPizzaList();

  /*! Static function : create a PizzaOrder object with the given string as
   * parameter and return the list of pizza generated
   * \param order : The order passed to PizzaOrder()
   * \return The list of \a Pizza generated by PizzaOrder
   */
  static std::list<Pizza> GetPizzaListFromOrder(const std::string &order);

private:
  /*! Disallow copy constructor and assignment operator */
  DISALLOW_COPY_AND_ASSIGN(PizzaOrderParser);

  /*! Type of tokens */
  enum eTokensType {
    PIZZA_TYPE,
    PIZZA_SIZE,
    PIZZA_QUANTITY
  };

  /*! Parse the order and create the pizza list */
  void Parse();
  /*! Parse the pizza's informations
   * \param tokenizerInfos : the tokenizer related to the pizza's informations
   * \param id : the pizza's information string position in the order string
   */
  void ParsePizza(utils::Tokenizer &tokenizerInfos, int id);
  /*! Convert the given string to a Pizza::PizzaType
   * \param string : the string to convert
   * \param the type of the pizza
   */
  Pizza::PizzaType ParsePizzaGetType(std::string string);
  /*! Convert the given string to a Pizza::PizzaSize
   * \param string : the string to convert
   * \param the size of the pizza
   */
  Pizza::PizzaSize ParsePizzaGetSize(std::string string);
  /*! Convert the given string to an integer representing the amount of pizza.
   * The string must be of the following format: "x[n]" where [n] is an integer
   * \param string : the string to convert
   * \param the amount of pizza
   */
  unsigned int ParsePizzaGetAmount(std::string string);

  std::string mOrder; /*!< The order given by the user */
  std::list<Pizza> mPizzaList; /*!< The pizza list */
  utils::Tokenizer mTokenizerPizza; /*!< Tokenizer for each pizza */
  /*! Valid tokens */
  std::map<enum eTokensType, std::list<std::string> > mValidTokens;
}
;

} /* !namespace pizzeria */
#endif /* !PIZZAORDER_HPP_ */
